﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using XML_VML.Object;

namespace XML_VML
{
    public class DrawableLine : ContentControl
    {

        #region StartPoint
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
                "StartPoint",
                typeof(Point),
                typeof(DrawableLine),
                new FrameworkPropertyMetadata(new Point(), StartPointChanged));

        private static void StartPointChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var temp = dependencyObject as DrawableLine;
            var newvalue = (Point)eventArgs.NewValue;
            if (temp != null && newvalue != null)
            {
                temp.GetData().From = newvalue;
            }
        }

        public Point StartPoint
        {
            get { return (Point)GetValue(StartPointProperty); }
            set
            {
                if (StartPoint != value)
                {
                    SetValue(StartPointProperty, value);
                }
            }
        }
        #endregion

        #region EndPoint
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
                "EndPoint",
                typeof(Point),
                typeof(DrawableLine),
                new FrameworkPropertyMetadata(new Point(), EndPointChanged));

        private static void EndPointChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var temp = dependencyObject as DrawableLine;
            var newvalue = (Point)eventArgs.NewValue;
            if (temp != null && newvalue != null)
            {
                temp.GetData().To = newvalue;
            }
        }

        public Point EndPoint
        {
            get { return (Point)GetValue(EndPointProperty); }
            set
            {
                if (EndPoint != value)
                {
                    SetValue(EndPointProperty, value);
                }
            }
        }
        #endregion

        #region StrokeColor
        public Color StrokeColor
        {
            get
            {
                if (_data.Stroke)
                {
                    try
                    {
                        var color = (Color)ColorConverter.ConvertFromString(_data.StrokeColor);
                        return color;
                    }
                    catch (Exception)
                    {
                        return Colors.Black;
                    }
                }
                return Colors.Transparent;
            }
            set { _data.StrokeColor = value.ToString(); }
        }
        #endregion

        #region StrokeWeight

        public float StrokeWeight
        {
            get { return _data.StrokeWeight; }
            set { _data.StrokeWeight = value; }
        }
        #endregion

        #region FillColor
        public Color FillColor
        {
            get
            {
                if (_data.Fill)
                {
                    try
                    {
                        var color = (Color)ColorConverter.ConvertFromString(_data.FillColor);
                        return color;
                    }
                    catch (Exception)
                    {
                        return Colors.White;
                    }
                }
                return Colors.White;
            }
            set { _data.StrokeColor = value.ToString(); }
        }
        #endregion

        private VLine _data;

        public VLine GetData()
        {
            return _data;
        }

        public void SetData(VLine data)
        {
            _data = data;
            StartPoint = _data.From;
            EndPoint = _data.To;
        }

        static DrawableLine()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DrawableLine), new FrameworkPropertyMetadata(typeof(DrawableLine)));
        }

        protected bool IsDragging;
        private Point _clickPosition;

        public DrawableLine()
        {
            MouseLeftButtonDown += ControlMouseLeftButtonDown;
            MouseLeftButtonUp += ControlMouseLeftButtonUp;
            MouseMove += ControlMouseMove;
        }

        private void ControlMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IsDragging = true;
            var draggableControl = sender as Control;
            _clickPosition = e.GetPosition(this);
            if (draggableControl != null) draggableControl.CaptureMouse();
        }

        private void ControlMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsDragging = false;
            var draggable = sender as Control;

            if (draggable == null) return;
            var transform = draggable.RenderTransform as TranslateTransform;
            if (transform != null)
            {
                _data.From = new Point(_data.From.X + transform.Value.OffsetX, _data.From.Y + transform.Value.OffsetY);
                _data.To = new Point(_data.To.X + transform.Value.OffsetX, _data.To.Y + transform.Value.OffsetY);
                StartPoint = _data.From;
                EndPoint = _data.To;
            }
            draggable.RenderTransform = new TranslateTransform();
            draggable.ReleaseMouseCapture();
        }

        private void ControlMouseMove(object sender, MouseEventArgs e)
        {
            var draggableControl = sender as Control;

            if (!IsDragging || draggableControl == null) return;
            var currentPosition = e.GetPosition(Parent as UIElement);

            var transform = draggableControl.RenderTransform as TranslateTransform;
            if (transform == null)
            {
                transform = new TranslateTransform();
                draggableControl.RenderTransform = transform;
            }

            transform.X = currentPosition.X - _clickPosition.X;
            transform.Y = currentPosition.Y - _clickPosition.Y;
        }
    }
}
